import BasicConfig from "@/utils/config";
import {
	formatToken,
	tansParams
} from "./tool";
import errorCode from "./errorCode";
import {
	apiUrl
} from "../env";
import {
	useGetRefreshTokenStorage,
	useGetTokenStorage,
} from "../../hooks/useStorage";
import {
	useRefreshToken
} from "../../hooks/useLogin";
import http from "@/utils/http/hub";
import {
	eventBus
} from "../../enums/eventBus";
import encrypt from "../encrypt";
/**
 * 请求池
 * 保存上一次请求,如果token过期,无感刷新token后再次请求
 */
const RequestPool = [];
const _fnSetPool = (config) => {
	const index = RequestPool.findIndex(
		(r) => r.url === config.url && config.custom.auth
	);
	if (index < 0) {
		RequestPool.push(config);
	}
	// console.log("填充 RequestPool~~~", uni.$u.deepClone(RequestPool));
};
const _fnRequestAgain = async (config) => {
	const currentConfig = RequestPool.find((r) => r.url === config.url);
	if (currentConfig) {
		const {
			url,
			custom,
			method,
			data,
			params
		} = currentConfig;
		await useRefreshToken();
		console.log("刷新token后参数", method, params, data);
		return new Promise(async (resolve) => {
			const newData = await http[method.toLowerCase()]({
				url,
				params: method === "POST" ? data : params,
				config: {
					custom,
				},
			});
			resolve(newData);
		});
	}
};
let requestData = null;
const config = (vm) => {
	// 初始化请求配置
	uni.$u.http.setConfig((config) => {
		/* config 为默认全局配置*/
		config.baseURL = apiUrl;
		return config;
	});
	// 请求拦截
	uni.$u.http.interceptors.request.use(
		(config) => {
			// console.log("请求拦截", config);
			const token = useGetTokenStorage();
			if (config && config.custom) {
				const {
					loading,
					auth,
					postMountParams,
					refreshToken = true,
				} = config.custom;
				if (loading) {
					uni.showLoading({
						title: "加载中",
					});
				}
				if (auth) {
					config.header.Authorization = formatToken(token, config.custom);
				}
				if (postMountParams) {
					config.url = `${config.url}?${tansParams(config.data)}`;
				}
			}
			// 初始化请求拦截器时，会执行此方法，此时data为undefined，赋予默认{}
			config.data = config.data || {};
			requestData = config.data;
			// const {
			// 	sign,
			// 	timestamp
			// } = encrypt(
			// 	`/api${config.url}`,
			// 	config.method === "GET" ? config.params : config.data
			// );
			const {
				sign,
				timestamp,
				nonce
			} = encrypt(`/api${config.url}`, config.data, config.method.toLocaleLowerCase());
			console.log("encrypt", sign, timestamp);
			config.header.sign = sign;
			config.header.timestamp = timestamp;
			config.header.nonce = nonce;
			config.header.device = "h5";
			// config.header.recommendation = "";
			_fnSetPool(config);
			// console.log("请求拦截", config);
			return config;
		},
		(config) => {
			// 可使用async await 做异步操作
			return Promise.reject(config);
		}
	);
	let failCode = null;
	// 响应拦截
	uni.$u.http.interceptors.response.use(
		async (response) => {
				console.log("响应拦截", response);
				/* 对响应成功做点什么 可使用async await 做异步操作*/
				if (response.config?.custom?.loading) {
					uni.hideLoading();
				}
				let data = response.data;
				// 自定义参数
				const custom = response.config?.custom;
				// console.log("RequestPool~~~1", uni.$u.deepClone(RequestPool));
				if (data.code !== errorCode.overToken) {
					const index = RequestPool.findIndex(
						(r) => r.url === response.config.url
					);
					RequestPool.splice(index, 1);
				}
				// token过期 无感刷新token
				if (data.code === errorCode.overToken) {
					const oldToken = useGetTokenStorage();
					console.log("token过期.........oldToken:", oldToken);
					failCode = errorCode.overToken;
					if (!!oldToken) {
						console.log("!!oldToken uni.$emit");
						uni.$emit(
							eventBus.login.popup,
							true,
							"请求拦截~overToken !!oldToken"
						);
					} else {
						data = await _fnRequestAgain(response.config);
					}
				} else if (data.code !== errorCode.success) {
					// 如果没有显式定义custom的toast参数为false的话，默认对报错进行toast弹出提示
					if (custom.toast !== false) {
						// uni.$u.toast(data.message || data.msg);
						BasicConfig.toast(data.message || data.msg);
					}
					// 如果需要catch返回，则进行reject
					if (custom?.catch) {
						// return Promise.reject(data);
						return Promise.resolve(data);
					} else {
						// 否则返回一个pending中的promise，请求不会进入catch中
						return new Promise(() => {});
					}
				}
				// console.log("RequestPool~~~2", uni.$u.deepClone(RequestPool));
				return data ?? {};
			},
			(response) => {
				// console.log("catch", response);
				if (response.config?.custom?.loading) {
					uni.hideLoading();
				}
				if (failCode === errorCode.overToken) {
					uni.$emit(eventBus.login.popup, true, "请求拦截~catch");
				}

				// 对响应错误做点什么 （statusCode !== 200）
				return Promise.reject(response);
			}
	);
};

export default config;